Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(svelte-form): Add Svelte adapter #1247

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

dummdidumm
Copy link

This implements a Svelte adapter for the form package. API-wise it's somewhere inbetween Solid and React (createForm is used like Solid's, getting the field state from within a snippet is more like React). Added basic tests and two examples.

Superseeds #1107

43081j and others added 11 commits January 5, 2025 22:07
Absolutely untested, written without running it or trying it out in any
way. Just a very rough start written off the top of my head with the
help of various bits of docs.
- one Field component with a module script with createField in it
- createForm file
- bunch of types that pass along generics, closely modeled after the other adapters
- tests
Copy link

nx-cloud bot commented Mar 7, 2025

View your CI Pipeline Execution ↗ for commit 55e5c82.

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ❌ Failed 1m 56s View ↗
nx run-many --target=build --exclude=examples/** ✅ Succeeded 27s View ↗

☁️ Nx Cloud last updated this comment at 2025-03-17 10:45:37 UTC

</div>
</form>

<pre>{JSON.stringify(form.state, null, 2)}</pre>
Copy link
Member

@lachlancollins lachlancollins Mar 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be reactive, even replacing it with form.state.values.firstName doesn't update

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a leftover from some early explorations - I just removed it. FWIW for Solid and Vue this is also unreactive, from what I understand you gotta use form.useStore(...) to get a reactive version of (a part of) the state.

@lachlancollins lachlancollins mentioned this pull request Mar 8, 2025
5 tasks
@43081j
Copy link

43081j commented Mar 8, 2025

Let me know if you want any help with this 👍 my pr went stale since I was in need of someone to pair/review with but I am still very much interested in landing this

],
"dependencies": {
"@tanstack/form-core": "workspace:*",
"@tanstack/svelte-store": "^0.7.0"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should come from workspace:* I think

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't part of the monorepo, so like this is the correct way

} from '@tanstack/form-core'
import { useStore } from '@tanstack/svelte-store'
import { onMount, type Snippet } from 'svelte'
import Field from './Field.svelte'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is really, really odd. importing the file we're in, from the file we're in

i'm surprised this did something. even if this somehow works, we really shouldn't be doing it imo

this is why createField and Field were originally separate

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why shouldn't we? This is valid JavaScript, you can self-import in ESM, it's part of the spec. This is just a different way of doing what the other adapters are doing, where they have Field and createField in the same file.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its basically a hacky workaround for the fact there's a circular dependency here (createField needs Field and vice versa), and in svelte the component is the module as a whole

ideally, we'd figure it out properly. though im not sure how off the top of my head

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you running into a problem with the circular ref? In general it's ok due to the way js imports work (e.g., you can import yourself), but ideally something we resolve.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im fully aware that this "works", its just not great for code quality/readability and is inconsistent with the rest of the codebase

also its a clear workaround for the circular dependency. you did this because you couldn't define Field in the file itself (since it is the file), whereas in all other integrations we would just have it in a named export

i disagree with doing it this way but will leave it up to other reviewers to decide

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're not gonna get a "clean" solution because there's a cyclic dependency here. So either you have a cyclic import or you have a self-import - I prefer the latter due to colocation.

extendedApi.createField = (props) =>
createField(() => {
return { ...props(), form: api }
}) as never
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how come you weren't able to type this properly? (i.e. without as never)

Copy link
Author

@dummdidumm dummdidumm Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a comment; TS throws an error here that type instantiation is excessively deep (same as for Solid FWIW)

@Dreaming-Codes
Copy link

Is this ready for testing it in a project?

@niemyjski
Copy link

Is this ready for testing it in a project?

And if it is, would love to know if there is a nightly build :), Otherwise what is left / where we can help.

@JonathonRP
Copy link

Is this ready for testing it in a project?

what is left / where we can help.

I see an error in types that has an @ts/error with no actual error, and as someone else pointed that import failing. I think the reviews need to approve and best guess they will once those two failing tests pass from the fixes I mentioned...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants